package com.example.stack;

/**
 * @className: StackByArray
 * @description: 使用数组实现栈
 * @author: LiuZhenHe
 * @date: 2024/01/12 16:37
 **/
public class ArrayStack2 {
    public static void main(String[] args) {
        String formula = "30+20*6-20";
        // 创建两个栈，一个数字栈，一个符号栈
        ArrayStack2 numStack = new ArrayStack2(10);
        ArrayStack2 operatorStack = new ArrayStack2(10);
        int res = 0;
        char ch = 0;
        int num1 = 0;
        int num2 = 0;
        int oper = 0;
        int index = 0;
        while (true) {
            if (index >= formula.length()) {
                break;
            }
            // 截取要计算的字符
            ch = formula.substring(index, index + 1).charAt(0);
            index++;
            // 入栈
            // 如果是符号，入符号栈
            if (operatorStack.isOperator(ch)) {
                // 如果符号栈不为空
                if (!operatorStack.isEmpty()) {
                    // 如果当前符号的优先级小于栈顶的符号（表示当前计算的优先级没有上一个高）
                    // 则从数字栈中pop出两个数据,再从符号栈中pop出运算符进行计算，然后将计算完毕的值push到数栈中去
                    if (operatorStack.priority(ch) <= operatorStack.priority(operatorStack.getStackTopData())) {
                        num1 = numStack.pop();
                        num2 = numStack.pop();
                        oper = operatorStack.pop();
                        res = numStack.cal(num1, num2, oper);
                        numStack.push(res);
                        operatorStack.push(ch);
                    } else {
                        operatorStack.push(ch);
                    }
                } else {
                    operatorStack.push(ch);
                }
            } else {
                if (index < formula.length()) {
                    String tempNumber = "";
                    tempNumber = String.valueOf(ch);
                    while (true) {
                        if (index < formula.length() && !operatorStack.isOperator(formula.substring(index, index + 1).charAt(0))) {
                            tempNumber += String.valueOf(formula.substring(index, index + 1));
                            index++;
                        } else {
                            break;
                        }
                    }
                    numStack.push(Integer.valueOf(tempNumber));
                    tempNumber = "";
                } else {
                    numStack.push(ch - 48);
                }
            }
        }

        while (true) {
            // 如果符号栈为空，表示已计算完毕，打印最终值并退出循环
            if (operatorStack.isEmpty()) {
                System.out.println(numStack.pop());
                break;
            }
            num1 = numStack.pop();
            num2 = numStack.pop();
            oper = operatorStack.pop();
            res = numStack.cal(num1, num2, oper);
            numStack.push(res);
        }

    }

    // 栈的最大容量
    private int maxSize;
    // 用于存放数据
    private int[] array;
    // 指针，指向栈顶
    private int topIndex = -1;

    public ArrayStack2(int maxSize) {
        this.maxSize = maxSize;
        this.array = new int[maxSize];
    }

    public boolean isFull() {
        return topIndex == maxSize - 1;
    }

    public boolean isEmpty() {
        return topIndex == -1;
    }

    public void push(int number) {
        if (isFull()) {
            System.out.println("栈容量已满，无法继续添加数据");
            return;
        }
        topIndex++;
        array[topIndex] = number;
    }

    public int pop() {
        if (isEmpty()) {
            System.out.println("栈中没有数据，请先添加数据");
            return 0;
        }
        int value = array[topIndex];
        topIndex--;
        return value;
    }

    /**
     * 遍历栈
     */
    public void list() {
        while (true) {
            if (isEmpty()) {
                break;
            }
            System.out.println(pop());
            ;
        }
    }

    /**
     * 遍历栈，方式2
     * 从顶部开始遍历
     */
    public void list2() {
        if (isEmpty()) {
            System.out.println("栈中没有数据，请先添加数据");
            return;
        }
        for (int i = topIndex; i >= 0; i--) {
            System.out.printf("stack[%d]=%d\n", i, array[i]);
        }
    }

    // 获取栈顶数据
    public int getStackTopData() {
        return array[topIndex];
    }

    public int priority(int operator) {
        if (operator == '/' || operator == '*') {
            return 1;
        } else {
            return 0;
        }
    }

    public boolean isOperator(char operator) {
        return operator == '/' || operator == '*' || operator == '+' || operator == '-';
    }

    public int cal(int num1, int num2, int operator) {
        int result = 0;
        if (operator == '+') {
            result = num1 + num2;
        } else if (operator == '-') {
            result = num2 - num1;
        } else if (operator == '*') {
            result = num1 * num2;
        } else if (operator == '/') {
            result = num2 / num1;
        }
        return result;
    }

}
